\indent Tal como se especifica en el enunciado del trabajo práctico este filtro no es el mejor candidato para paralelizar utilizando instrucciones simd. La raz\'on de ello es que los p\'ixeles contiguos de la imagen resultante provienen de pixeles no contiguos de la imagen original, generalmente de filas distintas. Esto genera que para escribir los pixeles de la imagen resultante de manera ordenada haya que leer pixeles de la imagen original individualmente desde posiciones arbitrarias, no pudiendo por ello reducir la cantidad de accesos a memoria de lectura.

\indent Sin embargo la dificultad de este filtro radica no en operar sobre los píxeles de origen sino en averiguar cuales son estos p\'ixeles a partir de las posiciones de destino. Como los c\'alculos necesarios involucran operaciones de punto flotante y los registros xmm pueden operar con cuatro elementos de este tipo de datos, decidimos que era adecuado procesar cuatro posiciones de p\'ixeles de forma simult\'anea. Una vez hecho esto y obtenido los datos originales, procedemos a escribir los 4 datos de forma simult\'anea, reduciendo las escrituras en un factor de un cuarto.

\subsubsection{Carga de datos}

\indent En los registros $r10$ y $r11$ guardamos los \'indices de columna y fila respectivamente.

\subsubsection{Ciclo Principal}
\indent El primer paso del procedimiento es calcular los valores $u$ y $v$. El calculo inicial es id\'entico para los dos valores. Cargamos los 4 \'indices sobre los que vamos a operar en $xmm0$:

    \begin{center}
        \xmmxDWord{$c_1$}{$c_2$}{$c_3$}{$c_4$}
    \end{center}
en $xmm1$ cargamos los \'indices de la fila (siempre es el mismo)
    \begin{center}
        \xmmxDWord{$f_i$}{$f_i$}{$f_i$}{$f_i$}
    \end{center}

en $xmm2$ y $xmm3$ cargamos, en cada dword, el ancho y el alto dividido dos respectivamente. Convertimos todos los registros mencionados a float con la instrucci\'on $cvtdq2ps$. En $xmm4$ calculamos (de vuelta en cada dword) el valor $\sqrt{2}/2$. Calculamos en paralelo la diferencia entre los \'indices columna y $ancho/2$ y la diferencia entre los \'indices fila y $alto/2$.

\begin{itemize}
\item para $u$: para cada posici\'on calculamos $ancho/2 + \sqrt{2}/2 * indice_{columna} - ancho/2 - (indice_{fila} - alto/2)$. Finalmente convertimos los cuatro floats a enteros truncando.
\item para $v$: para cada posici\'on calculamos $alto/2 + \sqrt{2}/2 * indice_{columna} - ancho/2 + (indice_{fila} - alto/2)$. Finalmente convertimos los cuatro floats a enteros truncando.
\end{itemize}

Guardamos en $u$ en $xmm7$ y $v$ en $xmm0$:
    \begin{center}
        \xmmxDWord{$u_1$}{$u_2$}{$u_3$}{$u_4$}
    \end{center}
    \begin{center}
        \xmmxDWord{$v_1$}{$v_2$}{$v_3$}{$v_4$}
    \end{center}

En otros registros xmm cargamos el ancho y el alto replicados en cada dword. Comparamos en paralelo los valores $u$ con el ancho y el alto para ver si la posici\'on cae dentro de la imagen. Lo mismo para los valores $v$. Obtenemos de esta manera dos m\'ascaras. En las posiciones donde las dos m\'ascaras tengan unos, debemos usar los valores respectivos de $u$ y $v$ para obtener ese pixel en la imagen original. Sino, dejamos el pixel en negro. Utilizamos el registro $ECX$ para guardar los 4 bytes en el buffer de salida. La secuencia de pasos que se sigue es la siguiente:
\begin{enumerate}
\item Pongo en cero $ECX$
\item Si $u_4$ y $v_4$ estan en rango, copio dicho pixel en $cl$.
\item Shifteo $ECX$ 8 bits a la izquierda. Si $u_3$ y $v_3$ estan en rango, copio dicho pixel en $cl$.
\item Shifteo $ECX$ 8 bits a la izquierda. Si $u_2$ y $v_2$ estan en rango, copio dicho pixel en $cl$.
\item Shifteo $ECX$ 8 bits a la izquierda. Si $u_1$ y $v_1$ estan en rango, copio dicho pixel en $cl$.
\end{enumerate}

\indent Finalmente, escribo $ECX$ en el buffer de salida. Incremento los \'indices y paso a la siguiente iteraci\'on.

